package cc.telecomdigital.tdstock.trading.Common;

import java.math.BigDecimal;
import java.math.RoundingMode;

import android.os.Parcel;
import android.os.Parcelable;

import cc.telecomdigital.tdstock.trading.Tools.Trade_StockFunctionTools;

public class Trade_StockViewInfoItem  implements Parcelable
{
	// Basic Stock information
	public String		stockCode;
	public String		chnName;
	public String		engName;

	// Setting information
	public String		stepPrice;
	public String		stepVolume;		// lot Size
	public String       currencyCode;

	// Price Information
	private String		startPrice;
	private String		curPrice;		// Nominal
	private String		bidPrice;
	private String		askPrice;
	private boolean	isDropped;

	private String		diffPrice;
	private String		diffPercentage;

	/** Deep Copy of the stock item **/
	public Trade_StockViewInfoItem(Trade_StockViewInfoItem iItem)
	{
		if (iItem != null)
		{
			stockCode = iItem.stockCode;
			chnName = iItem.chnName;
			engName = iItem.engName;
			startPrice = iItem.startPrice;
			curPrice = iItem.curPrice;
			bidPrice = iItem.bidPrice;
			askPrice = iItem.askPrice;
			diffPrice = iItem.diffPrice;
			diffPercentage = iItem.diffPercentage;
			stepPrice = iItem.stepPrice;
			stepVolume = iItem.stepVolume;
			currencyCode = iItem.currencyCode;
			isDropped = iItem.isDropped;
		}
	}

	/** Current Viewing stock info, on keypad **/
	public Trade_StockViewInfoItem(String iCode, String iChnName,
			String iEngName)
	{
		stockCode = iCode;
		chnName = iChnName;
		engName = iEngName;

		curPrice = null;
		bidPrice = null;
		askPrice = null;
		diffPrice = null;
		diffPercentage = null;

		stepVolume = null;
		stepPrice = null;
		isDropped = false;
		currencyCode = null;
	}

	/** Set the starting price of the viewing start, usually the open price from server **/
	public void SetStartPrice(String iStartPrice, boolean iCalculateDiff)
	{
		startPrice = iStartPrice;
		if (startPrice != null)
			startPrice = startPrice.replace(",", "");

		// Calculate the difference if possible
		if (iCalculateDiff)
			UpdateDiffPrice(curPrice, startPrice);
	}

	/** Set the starting price of the viewing start, the nominal price from server **/	
	public void SetCurPrice(String iCurPrice, boolean iCalculateDiff)
	{
		curPrice = iCurPrice;
		if (curPrice != null)
			curPrice = curPrice.replace(",", "");

		if (iCalculateDiff)
			UpdateDiffPrice(curPrice, startPrice);
	}

	/** Set the Bid Price from Server **/		
	public void SetBidPrice(String iBidPrice)
	{
		bidPrice = iBidPrice;
		if (bidPrice != null)
			bidPrice = bidPrice.replace(",", "");
	}

	/** Set the Ask Price from Server **/	
	public void SetAskPrice(String iAskPrice)
	{
		askPrice = iAskPrice;
		if (askPrice != null)
			askPrice = askPrice.replace(",", "");
	}

	/** Replace all price info **/
	public void SetPriceInfo(String iCurPrice, String iBidPrice,
			String iAskPrice, boolean iCalculateDiff)
	{
		SetBidPrice(iBidPrice);
		SetAskPrice(iAskPrice);
		SetCurPrice(iCurPrice, iCalculateDiff);
	}

	/** Once the opening price and curPrice are valid, diff will be calculated **/
	void UpdateDiffPrice(String iCurPrice, String iStartPrice)
	{
		if ((iCurPrice == null) || (iStartPrice == null) 
			|| (iCurPrice.length() == 0) || (iStartPrice.length() == 0))
		{
			diffPrice = "0.00";
			diffPercentage = "0.00";
			isDropped = false;
			return;
		}

		try
		{
			String tmpValue;
			BigDecimal conversion;

			diffPrice = Trade_StockFunctionTools.CalculateDiffInPrice(
					iCurPrice, iStartPrice);

			// Usually comes to 0.001 and prepare for the 100% overwritten
//			tmpValue = Trade_StockFunctionTools.CalculateQuotientInPrice(					
//					diffPrice, iCurPrice);
			tmpValue = Trade_StockFunctionTools.CalculateQuotientInPrice(
					diffPrice, iStartPrice);			
			tmpValue = Trade_StockFunctionTools.CalculateProductInPrice(
					tmpValue, "100");
			conversion = new BigDecimal(tmpValue);
			diffPercentage = conversion.setScale(3, RoundingMode.HALF_DOWN)
					.stripTrailingZeros().toPlainString();

			if (diffPrice.startsWith("-") == false)
			{
				diffPrice = "+" + diffPrice;
				diffPercentage = "+" + diffPercentage;
				isDropped = false;
			}
			else
				isDropped = true;
		}
		catch (Exception ex)
		{
			diffPrice = "0.00";
			diffPercentage = "0.00";
			isDropped = false;
		}
	}

	/** Just For Storage, however it must be a whole number **/
	public void SetStepVolume(String iStepVolume)
	{
		stepVolume = iStepVolume;
		if ((stepVolume != null) && (stepVolume.length() > 0))
		{
			BigDecimal converter;
			String tmpString;

			tmpString = stepVolume.replace(",", "");
			converter = new BigDecimal(tmpString);
			converter = converter.setScale(0, RoundingMode.UNNECESSARY);
			stepVolume = converter.toPlainString();
		}
	}

	public void SetCurrencyCode(String iCurCode)
	{
		currencyCode = iCurCode;
	}
	
	/* Setting this Diff would override the internal
	 * calculation for the diff price and diff percentage
	 */
	public void SetNetDiffPrice(String iDiff, String iDiffPercentage)
	{
		diffPrice = iDiff;
		diffPercentage = iDiffPercentage;
		if ((iDiff != null) && (iDiff.subSequence(0, 1).equals("-")))
			isDropped = true;
		else
			isDropped = false;
	}
	
	/** Spread price for the stock **/
	public void SetSpreadPrice(String iSpreadPrice)
	{
		stepPrice = iSpreadPrice;
		if (stepPrice != null)
			stepPrice = stepPrice.replace(",", "");
	}

	/** Obtain whether the stock is on drop or on rise **/
	public boolean IsDropped()
	{
		return isDropped;
	}

	/** Get the current price in text with formatted "," on every thousand **/
	public String GetCurPriceText()
	{
		if ((curPrice == null) || (curPrice.length() == 0))
			return "";

		return Trade_StockFunctionTools.AutoFillInDecimal(curPrice,
				Trade_AppConstant.priceValueStringWithDec);
	}

	/** Get the bid price in text with formatted "," on every thousand **/	
	public String GetCurBidPriceText()
	{
		if ((bidPrice == null)  || (bidPrice.length() == 0))
			return "";

		return Trade_StockFunctionTools.AutoFillInDecimal(bidPrice,
				Trade_AppConstant.priceValueStringWithDec);
	}

	/** Get the ask price in text with formatted "," on every thousand **/	
	public String GetCurAskPriceText()
	{
		if ((askPrice == null)  || (askPrice.length() == 0))
			return "";

		return Trade_StockFunctionTools.AutoFillInDecimal(askPrice,
				Trade_AppConstant.priceValueStringWithDec);
	}

	public enum StockPriceDiffFormat
	{
		PRICE, PERCENTAGE, FULL
	}

	/** Get the difference price in text with formatted "," on every thousand **/	
	public String GetPriceDifferenceText(StockPriceDiffFormat iFormat)
	{
		String formatString;
		String firstOne;
		
		switch (iFormat)
		{
			case PRICE:
				formatString =  Trade_StockFunctionTools.AutoFillInDecimal(
							diffPrice, Trade_AppConstant.priceValueStringWithDec);
				if ((formatString == null ) || (formatString.length() == 0))
					return "---";
									
				firstOne = formatString.substring(0, 1);
				if (!firstOne.equals("-") && !firstOne.equals("+"))
					formatString =  "+" + formatString;
								
				return formatString;

			case PERCENTAGE:
				if ((diffPercentage == null ) || (diffPercentage.length() == 0))
					 return "(---%)";
				
				firstOne = diffPercentage.substring(0, 1);
				if (!firstOne.equals("-") && !firstOne.equals("+"))
					formatString =  "+" + diffPercentage;
				return  "(" + diffPercentage + "%" + ")";

			case FULL:
				String fullString;
				formatString =  Trade_StockFunctionTools.AutoFillInDecimal(diffPrice,
							 Trade_AppConstant.priceValueStringWithDec);
				if ((formatString == null ) || (formatString.length() == 0))
					formatString = "---";
				else
				{					
					firstOne = formatString.substring(0, 1);
					if (!firstOne.equals("-") && !firstOne.equals("+"))
						formatString =  "+" + formatString;
				}
				fullString = formatString;
				
				if ((diffPercentage == null ) || (diffPercentage.length() == 0))
					formatString = " (---%)";
				else
				{
				    formatString =  diffPercentage + "%" + ")";
				    firstOne = formatString.substring(0, 1);
				    if (!firstOne.equals("-") && !firstOne.equals("+"))
					   formatString = " (+" + formatString;
				    else
					   formatString = " (" + formatString;
				}															
				return fullString + formatString;				
		}
		return "";
	}
	
	public String toString()
	{
		String retString;
		
		retString  = stockCode + "," + chnName + "," + engName + ",";
		retString += currencyCode + "," + startPrice + ","  + curPrice + "," + bidPrice + "," + askPrice + "," 
				+ diffPrice + "," + diffPercentage + ",";
		retString += stepPrice + "," + stepVolume;
			
		return retString;
	}

	static private int parcelStringMember = 12;
	/** Parcel able function call **/
	@Override
	public void writeToParcel(Parcel out, int iFlag)
	{
		// Write has the same sequence of read
		out.writeStringArray(new String[] { stockCode, chnName, engName, 
									 stepPrice, stepVolume, currencyCode,
									 startPrice, curPrice, bidPrice, 
									 askPrice, diffPrice, diffPercentage}
						 );

		out.writeBooleanArray(new boolean[]{isDropped});			
	}

	public static final Parcelable.Creator<Trade_StockViewInfoItem>	CREATOR	= new Parcelable.Creator<Trade_StockViewInfoItem>()
																{
																	public Trade_StockViewInfoItem createFromParcel(
																			Parcel in)
																	{
																		return new Trade_StockViewInfoItem(
																				in);
																	}

																	public Trade_StockViewInfoItem[] newArray(
																			int size)
																	{
																		return new Trade_StockViewInfoItem[size];
																	}
																};

	private Trade_StockViewInfoItem(Parcel in)
	{
		String[] inStrArray;
		boolean[] inBoolArray;
		
		inStrArray = new String[parcelStringMember];		
		in.readStringArray(inStrArray);
		
		stockCode = inStrArray[0];
		chnName = inStrArray[1];
		engName = inStrArray[2];
		stepPrice = inStrArray[3];
		stepVolume = inStrArray[4];
		currencyCode = inStrArray[5];
		startPrice = inStrArray[6];
		curPrice = inStrArray[7];
		bidPrice = inStrArray[8];
		askPrice = inStrArray[9];
		diffPrice = inStrArray[10];
		diffPercentage = inStrArray[11];		
		
		inBoolArray = new boolean[1];
		in.readBooleanArray(inBoolArray);		
		isDropped = inBoolArray[0];
	}

	@Override
	public int describeContents()
	{
		return 0;
	}
}
